use crate::nlp::{Embedding, Intent, IntentClassifier, Tokenizer};
use crate::transformer::Transformer;

/// 对话管理器
pub struct DialogueManager {
    tokenizer: Tokenizer,
    embedding: Embedding,
    transformer: Option<Transformer>,
    intent_classifier: IntentClassifier,
    knowledge_base: KnowledgeBase,
    context: Vec<String>,
}

impl DialogueManager {
    /// 创建对话管理器
    pub fn new(transformer: Option<Transformer>) -> Self {
        let mut tokenizer = Tokenizer::new();
        
        // 构建词表
        let vocab = vec![
            "你", "好", "您", "我", "是", "的", "吗", "什么", "能", "做",
            "会", "可以", "有", "功能", "介绍", "一下", "自己", "谁",
            "AI", "系统", "神经", "符号", "推理", "学习", "识别", "分类",
            "诊断", "预测", "理解", "问答", "对话", "帮助", "如何", "为什么",
            "Transformer", "注意力", "机制", "模型", "训练", "测试",
            "你好", "您好", "再见", "谢谢", "不", "是的", "好的",
            "人工智能", "深度学习", "机器学习", "自然语言", "处理",
        ];

        for word in vocab {
            tokenizer.add_word(word);
        }

        let embedding = Embedding::new(tokenizer.vocab_size(), 64);

        DialogueManager {
            tokenizer,
            embedding,
            transformer,
            intent_classifier: IntentClassifier::new(),
            knowledge_base: KnowledgeBase::new(),
            context: Vec::new(),
        }
    }

    /// 处理用户输入
    pub fn process(&mut self, user_input: &str) -> String {
        println!("\n=== 对话处理流程 ===");
        println!("用户输入: {}", user_input);

        // 1. 分词
        let tokens = self.tokenizer.tokenize(user_input);
        println!("分词结果: {:?}", tokens);

        // 2. 意图识别
        let intent = self.intent_classifier.classify(&tokens);
        println!("意图识别: {}", intent);

        // 3. 词嵌入
        let token_ids = self.tokenizer.encode(&tokens);
        let embeddings = self.embedding.get_batch(&token_ids);

        // 4. Transformer理解（如果可用）
        if let Some(transformer) = &self.transformer {
            let context_embeddings = transformer.forward(&embeddings);
            println!("Transformer处理: 生成上下文表示");
            
            // 简单地使用第一个token的表示作为句子表示
            if let Some(sentence_repr) = context_embeddings.first() {
                let avg: f64 = sentence_repr.iter().sum::<f64>() / sentence_repr.len() as f64;
                println!("句子表示强度: {:.4}", avg);
            }
        }

        // 5. 根据意图生成回复
        let response = self.generate_response(&intent, &tokens, user_input);

        // 6. 更新上下文
        self.context.push(user_input.to_string());
        if self.context.len() > 5 {
            self.context.remove(0);
        }

        response
    }

    /// 生成回复
    fn generate_response(&self, intent: &Intent, tokens: &[String], raw_input: &str) -> String {
        match intent {
            Intent::Greeting => self.handle_greeting(),
            Intent::Capability => self.handle_capability_query(),
            Intent::Question => self.handle_question(tokens, raw_input),
            Intent::Farewell => self.handle_farewell(),
            Intent::Help => self.handle_help(),
            Intent::Affirmative => "好的，我明白了。还有什么我可以帮您的吗？".to_string(),
            Intent::Negative => "好的，如果您有其他问题，随时告诉我。".to_string(),
            Intent::Unknown => self.handle_unknown(raw_input),
        }
    }

    fn handle_greeting(&self) -> String {
        use rand::Rng;
        let mut rng = rand::thread_rng();
        
        let greetings = vec![
            "你好！我是一个神经符号AI系统。我结合了深度学习和符号推理的能力。\n\n您可以问我：\n  • 我能做什么\n  • 什么是Transformer\n  • 什么是神经符号AI\n  • 如何使用系统",
            "您好！很高兴见到您！😊\n\n我是一个结合了神经网络和符号推理的AI助手。\n\n有什么我可以帮您的吗？",
            "嗨！欢迎使用神经符号AI系统！\n\n我可以回答技术问题、帮助您了解系统功能。\n\n请随意提问！",
        ];
        
        greetings[rng.gen_range(0..greetings.len())].to_string()
    }

    fn handle_capability_query(&self) -> String {
        let mut response = String::from("我是一个先进的神经符号AI系统，具有以下能力：\n\n");
        
        response.push_str("🧠 **神经网络能力**:\n");
        response.push_str("  • 多层感知器（MLP）- 模式识别\n");
        response.push_str("  • Linear Attention Transformer - 序列理解（O(n)复杂度）\n");
        response.push_str("  • 前向/反向传播训练\n");
        response.push_str("  • 支持ReLU、Sigmoid、Tanh等激活函数\n\n");

        response.push_str("🔍 **符号推理能力**:\n");
        response.push_str("  • 基于规则的逻辑推理\n");
        response.push_str("  • 前向链式推理（数据驱动）\n");
        response.push_str("  • 后向链式推理（目标驱动）\n");
        response.push_str("  • 置信度传播和推理解释\n\n");

        response.push_str("💼 **应用场景**:\n");
        response.push_str("  • 动物分类和生物特征推理\n");
        response.push_str("  • 医疗症状诊断和治疗建议\n");
        response.push_str("  • 天气预测和风险评估\n");
        response.push_str("  • 自然语言理解和问答\n\n");

        response.push_str("💾 **其他特性**:\n");
        response.push_str("  • 模型持久化（保存/加载）\n");
        response.push_str("  • 可解释的AI决策过程\n");
        response.push_str("  • 纯Rust实现，高性能、内存安全\n\n");

        response.push_str("您想了解哪个方面的更多细节吗？");
        
        response
    }

    fn handle_question(&self, tokens: &[String], raw_input: &str) -> String {
        let text = tokens.join("");
        
        // 先查询知识库
        if let Some(answer) = self.knowledge_base.query(raw_input) {
            return answer;
        }

        // 智能关键词匹配
        if text.contains("Transformer") || text.contains("transformer") {
            return "💡 **Transformer详解**\n\nTransformer是一种革命性的深度学习架构，2017年由Google提出。\n\n**我使用的Linear Attention变体**：\n• ⚡ 复杂度：O(n²) → O(n)\n• 🚀 速度提升：对长序列有100-1000倍加速\n• 📐 核心技巧：使用kernel trick避免显式计算注意力矩阵\n\n**主要组件**：\n• Position Encoding - 编码位置信息\n• Multi-Head Attention - 捕捉多方面语义\n• Feed-Forward Network - 非线性变换\n• Layer Normalization - 稳定训练\n\n**想看实际效果？**\n运行: cargo run --example transformer_demo".to_string();
        }

        if text.contains("神经符号") || text.contains("结合") || text.contains("什么是") && text.len() < 20 {
            return "🤖 **神经符号AI (Neuro-Symbolic AI)**\n\n这是AI的未来方向 - 结合两个世界的优势！\n\n**🧠 神经网络**：\n• 强于：感知、模式识别、学习\n• 弱于：逻辑推理、可解释性\n\n**🔍 符号推理**：\n• 强于：逻辑、知识表示、推理\n• 弱于：处理复杂现实数据\n\n**✨ 结合后的超能力**：\n• 既能\"看\"（感知）又能\"想\"（推理）\n• 既能学习又能应用规则\n• 既高效又可解释\n\n**实际例子**：\n医疗诊断 = 神经网络识别症状 + 符号推理推导治疗方案\n\n想看具体应用？试试: cargo run --release".to_string();
        }

        if text.contains("Linear") || text.contains("linear") || text.contains("复杂度") {
            return "⚡ **Linear Attention详解**\n\n传统Self-Attention的问题：O(n²)复杂度\n→ 处理长文本时，速度急剧下降\n\n**Linear Attention的魔法**：\n```\n标准: Softmax(QK^T)V    →  O(n²)\nLinear: φ(Q)(φ(K)^T V)  →  O(n)\n```\n\n**关键技术**：\n• 特征映射 φ(x) = elu(x) + 1\n• Kernel trick避免显式矩阵乘法\n• 累积计算KV避免重复\n\n**实际性能**：\n• 序列长度512：快200倍\n• 序列长度1024：快400倍\n\n运行demo体验: cargo run --example transformer_demo".to_string();
        }

        if text.contains("如何") || text.contains("怎么用") || text.contains("使用") {
            return "📚 **快速上手指南**\n\n**1. 运行示例**：\n```bash\n# 基础示例（动物分类、医疗诊断等）\ncargo run --release\n\n# Transformer演示\ncargo run --example transformer_demo\n\n# 对话系统（就是我！）\ncargo run --example chat_demo\n```\n\n**2. 代码使用**：\n```rust\nuse neurosymbolic_ai::*;\n\n// 创建神经网络\nlet mut nn = NeuralNetwork::new();\nnn.add_layer(Layer::new(3, 5, Activation::ReLU));\n\n// 训练\nnn.train_batch(&data, 0.1, 100);\n\n// 保存模型\nModelPersistence::save_neural_network_binary(&nn, \"model.bin\")?;\n```\n\n**3. 查看文档**：\n• README.md - 完整文档\n• docs/TRANSFORMER_GUIDE.md - Transformer指南\n\n还有什么不清楚的吗？".to_string();
        }

        if text.contains("能力") || text.contains("功能") {
            return self.handle_capability_query();
        }

        // 默认回复
        format!(
            "🤔 关于「{}」这个问题...\n\n很抱歉，我的知识库还没有覆盖这方面。\n\n**我能回答的问题**：\n• 什么是Transformer / Linear Attention\n• 什么是神经符号AI\n• 如何使用这个系统\n• 我有哪些能力\n\n**或者**您可以：\n• 查看 README.md 获取完整文档\n• 运行 cargo run --example transformer_demo 查看示例\n• 提出其他技术相关问题\n\n换个问题试试？😊",
            raw_input
        )
    }

    fn handle_farewell(&self) -> String {
        "再见！感谢使用神经符号AI系统。如果将来有任何问题，随时回来找我！👋".to_string()
    }

    fn handle_help(&self) -> String {
        "我可以帮您：\n\n💬 **对话功能**:\n  • 回答关于我能力的问题\n  • 解释神经符号AI的概念\n  • 介绍Transformer等技术\n\n🔧 **技术支持**:\n  • 如何使用本系统\n  • 如何训练模型\n  • 如何保存/加载模型\n\n📚 **学习资源**:\n  • 查看README.md了解详细功能\n  • 运行examples查看示例代码\n  • 阅读docs/获取技术文档\n\n请告诉我您需要什么帮助！".to_string()
    }

    fn handle_unknown(&self, raw_input: &str) -> String {
        format!(
            "抱歉，我不太理解\"{}\"的意思。\n\n您可以：\n• 问我\"你能做什么\"\n• 问我\"什么是Transformer\"\n• 说\"帮助\"查看我的功能\n\n试试用更明确的方式提问吧！",
            raw_input
        )
    }

    /// 获取对话上下文
    pub fn get_context(&self) -> &[String] {
        &self.context
    }
}

/// 知识库
struct KnowledgeBase {
    qa_pairs: Vec<(Vec<String>, String)>, // (关键词列表, 回答)
}

impl KnowledgeBase {
    fn new() -> Self {
        let mut kb = KnowledgeBase {
            qa_pairs: Vec::new(),
        };

        // 添加更多知识条目
        kb.add_entry(
            vec!["模型", "保存", "存储", "持久化"],
            "💾 **模型保存/加载**\n\n使用 ModelPersistence 工具：\n\n```rust\n// 保存（二进制，推荐）\nModelPersistence::save_neural_network_binary(&nn, \"model.bin\")?;\n\n// 加载\nlet nn = ModelPersistence::load_neural_network_binary(\"model.bin\")?;\n\n// JSON格式（可读性好）\nModelPersistence::save_neural_network(&nn, \"model.json\")?;\n```\n\n**文件大小对比**：\n• 二进制：~360 bytes\n• JSON：~2 KB\n\n推荐使用二进制格式，压缩率更高！",
        );

        kb.add_entry(
            vec!["训练", "学习", "优化"],
            "📈 **模型训练**\n\n```rust\nlet training_data = vec![\n    (vec![1.0, 0.0], vec![1.0, 0.0]),\n    (vec![0.0, 1.0], vec![0.0, 1.0]),\n];\n\n// 批量训练\nnn.train_batch(&training_data, 0.1, 1000);\n//                            ↑学习率  ↑轮数\n```\n\n**参数调优提示**：\n• 学习率：0.01-0.3（太小慢，太大不稳定）\n• 训练轮数：100-10000（看损失曲线）\n• 批量大小：影响训练速度和稳定性",
        );

        kb.add_entry(
            vec!["激活函数", "ReLU", "Sigmoid"],
            "⚡ **激活函数对比**\n\n• **ReLU**: 最常用，快速，但有\"神经元死亡\"问题\n  f(x) = max(0, x)\n\n• **Sigmoid**: 输出0-1，适合二分类，但梯度消失\n  f(x) = 1/(1+e^(-x))\n\n• **Tanh**: 输出-1到1，零中心化，收敛快\n  f(x) = tanh(x)\n\n**建议**：\n• 隐藏层：ReLU\n• 输出层（分类）：Sigmoid\n• 输出层（回归）：Linear（无激活）",
        );

        kb
    }

    fn add_entry(&mut self, keywords: Vec<&str>, answer: &str) {
        let keywords: Vec<String> = keywords.iter().map(|s| s.to_string()).collect();
        self.qa_pairs.push((keywords, answer.to_string()));
    }

    fn query(&self, question: &str) -> Option<String> {
        let question_lower = question.to_lowercase();
        
        // 计算每个条目的匹配分数
        let mut best_match: Option<(usize, &String)> = None;
        let mut best_score = 0;

        for (keywords, answer) in &self.qa_pairs {
            let mut score = 0;
            for keyword in keywords {
                if question_lower.contains(&keyword.to_lowercase()) {
                    score += 1;
                }
            }
            
            if score > best_score {
                best_score = score;
                best_match = Some((score, answer));
            }
        }

        // 至少匹配2个关键词才返回
        if best_score >= 2 {
            best_match.map(|(_, answer)| answer.clone())
        } else {
            None
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_dialogue_manager() {
        let mut dm = DialogueManager::new(None);
        let response = dm.process("你好");
        // 检查是否包含问候相关内容（因为有随机性）
        assert!(response.contains("你好") || response.contains("您好") || response.contains("欢迎") || response.contains("嗨"));
    }

    #[test]
    fn test_capability_query() {
        let mut dm = DialogueManager::new(None);
        let response = dm.process("你能做什么");
        assert!(response.contains("神经网络"));
        assert!(response.contains("符号推理"));
    }
}

